﻿using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using CthulhuDomain;
using CthulhuDomain.GameEntities;
using CthulhuDomain.StageManagement;
using Microsoft.Pex.Framework;
using Microsoft.Pex.Framework.Validation;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace Invaders.Test.Factories.GameEntities
{
  [TestClass]
  public partial class PlayerFixture
  {
    private static ContentManager contentManager;
    private SpriteBatchAdapter spriteBatch;
    private GameServiceManager gameServiceManager;

    [TestInitialize]
    public void TestInitialize() {
      var gd = new MockedGraphicsDeviceService(DeviceType.Hardware, GraphicsProfile.HiDef);
      gd.CreateDevice();

      string activeConfinguration;
#if DEBUG
      activeConfinguration = "Debug";
#else
      activeConfinguration = "Release";

#endif
      spriteBatch = new SpriteBatchAdapter(gd.GraphicsDevice);
      contentManager = new ContentManager(gd.ServiceProvider) {
        RootDirectory = Path.GetFullPath(string.Format("../../../CthulhuInvaders/bin/x86/{0}/Content/", activeConfinguration))
      };

      gameServiceManager = new GameServiceManager(new GameAdapter(new Game()), new ContentManagerAdapter(contentManager), spriteBatch, new RectangleAdapter(0, 0, 300, 300));
    }

    [TestCleanup]
    public void MyTestCleanup() {
      contentManager = null;
      spriteBatch = null;
      gameServiceManager = null;
    }

    [PexMethod]
    public void PressRight_PlayerXCoord_ShouldBeIncreased() {
      // Arrange
      var player = DomainFactory
        .GetFactory(DomainFactory.eTypeEntity.Player)
        .CreateEntity(new ContentManagerAdapter(contentManager), new PlayerState() { LifePoints = 3, StartingPosition = new Vector2Adapter(50, 50) });

      var oldXCoord = player.Position.X;
      // Act
      player.Update(gameServiceManager.Context, new[] { Keys.Right });
      // Assert
      Assert.IsTrue(player.Position.X > oldXCoord);
      Trace.WriteLine(string.Format("Old X Coord was: {0}; New X Coord is: {1}", oldXCoord, player.Position.X));

    }

    [PexMethod]
    public void PressLeft_PlayerXCoord_ShouldBeDecreasedOrSame() {
      // Arrange
      var player = DomainFactory
        .GetFactory(DomainFactory.eTypeEntity.Player)
        .CreateEntity(new ContentManagerAdapter(contentManager), new PlayerState() { LifePoints = 3, StartingPosition = new Vector2Adapter(50, 50) });

      var oldXCoord = player.Position.X;
      // Act
      player.Update(gameServiceManager.Context, new[] { Keys.Left });
      // Assert
      Assert.IsTrue(player.Position.X < oldXCoord);
      Trace.WriteLine(string.Format("Old X Coord was: {0}; New X Coord is: {1}", oldXCoord, player.Position.X));
    }

    [PexMethod]
    public void PressSpace_PlayerShoots_ShouldBeIncreasedByOne() {
      // Arrange
      var player = DomainFactory
        .GetFactory(DomainFactory.eTypeEntity.Player)
        .CreateEntity(new ContentManagerAdapter(contentManager), new PlayerState() { LifePoints = 3, StartingPosition = new Vector2Adapter(50, 50) });
      var oldCount = player.ShootsCount;
      // Act
      player.Update(gameServiceManager.Context, new[] { Keys.Space });
      // Assert
      Assert.AreEqual(1, player.ShootsCount);
      Trace.WriteLine(string.Format("Old Player shoots count was: {0}; New Player shoots count is: {1}", oldCount, player.ShootsCount));
    }

    [PexMethod]
    public void ShootOutOfContext_ShouldBeRemoved() {
      // Arrange
      var player = DomainFactory
        .GetFactory(DomainFactory.eTypeEntity.Player)
        .CreateEntity(new ContentManagerAdapter(contentManager), new PlayerState() { LifePoints = 3, StartingPosition = new Vector2Adapter(50, 50) });
      player.Update(gameServiceManager.Context, new[] { Keys.Space });
      var oldCount = player.ShootsCount;
      player.GetShoot(0).Position.Y = -1;
      // Act
      player.Update(gameServiceManager.Context, new[] { Keys.Left });
      // Assert
      Assert.AreEqual(0, player.ShootsCount);
      Trace.WriteLine(string.Format("Old Player shoots count was: {0}; New Player shoots count is: {1}", oldCount, player.ShootsCount));
    }

    [PexMethod]
    public void AddShoot_ShootCout_ShouldBeIncreasedByOne()
    {
      // Arrange
      var player = DomainFactory
        .GetFactory(DomainFactory.eTypeEntity.Player)
        .CreateEntity(new ContentManagerAdapter(contentManager), new PlayerState() { LifePoints = 3, StartingPosition = new Vector2Adapter(50, 50) });
      var oldCount = player.ShootsCount;
      // Act
      player.AddShoot();
      // Assert
      Assert.AreEqual(1,player.ShootsCount-oldCount);
      Trace.WriteLine(string.Format("Old Player shoots count was: {0}; New Player shoots count is: {1}",oldCount, player.ShootsCount));
    }
  }
}
